package com.meter.data.service.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.meter.basic.domain.BasicMeter;
import com.meter.basic.mapper.BasicMeterMapper;
import com.meter.common.config.datasource.DynamicDataSourceContextHolder;
import com.meter.common.enums.DataSourceType;
import com.meter.common.handler.MyTableNameHandler;
import com.meter.common.utils.DateUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.meter.common.annotation.DataSource;
import com.meter.common.utils.StringUtils;
import com.meter.config.domain.ConfigAlarm;
import com.meter.config.mapper.ConfigAlarmMapper;
import com.meter.data.domain.MeterData;
import com.meter.data.protocol.param.IecmParam;
import com.meter.data.service.IAlarmDataService;
import com.meter.rabbitmq.service.RabbitService;
import com.meter.redis.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.meter.data.mapper.MeterDataMapper;
import com.meter.data.service.IMeterDataService;
import com.meter.common.core.text.Convert;

/**
 * 热采集数据Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-10-05
 */
@Service
public class MeterDataServiceImpl extends ServiceImpl<MeterDataMapper, MeterData> implements IMeterDataService
{

    @Autowired
    private BasicMeterMapper basicMeterMapper;

    @Autowired
    private IAlarmDataService alarmDataService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private RabbitService rabbitService;

    @Autowired
    private IecmParam iecmParam;

    /**
     * 查询热采集数据列表
     * 
     * @param meterData 热采集数据
     * @return 热采集数据
     */
    @Override
    @DataSource(DataSourceType.SLAVE)
    public List<MeterData> selectMeterDataList(MeterData meterData)
    {
        String beginTime = meterData.getParams().get("beginTime").toString().isEmpty() ? DateUtils.getDate() : meterData.getParams().get("beginTime").toString();
        String endTime = meterData.getParams().get("endTime").toString().isEmpty() ? DateUtils.getDate() : meterData.getParams().get("endTime").toString();
        String beginMonth = beginTime.isEmpty() ? DateUtils.getMonth(new Date()) : DateUtils.getMonth(beginTime);
        String endMonth = endTime.isEmpty() ? DateUtils.getMonth(new Date()) : DateUtils.getMonth(endTime);
        List<MeterData> list = new ArrayList<>();
        while (DateUtils.parseMonth(endMonth).getTime() >= DateUtils.parseMonth(beginMonth).getTime()) {
            MyTableNameHandler.setData(beginMonth);
            List<MeterData> meterDataList = baseMapper.selectMeterDataList(meterData);
            list.addAll(meterDataList);
            MyTableNameHandler.removeData();
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(DateUtils.parseMonth(beginMonth));
            calendar.add(Calendar.MONTH, 1);
            beginMonth = DateUtils.getMonth(calendar.getTime());
        }
        return list;
    }

    /**
     * 修改热采集数据
     * 
     * @param meterData 热采集数据
     * @return 结果
     */
    @Override
    public int updateMeterData(MeterData meterData)
    {
        // 更新热表信息
        LambdaUpdateWrapper<BasicMeter> updateWrapper = Wrappers.lambdaUpdate(BasicMeter.class);
        updateWrapper.set(BasicMeter::getHeat, meterData.getHeat());
        updateWrapper.set(BasicMeter::getFlow, meterData.getFlow());
        updateWrapper.set(BasicMeter::getInlet, meterData.getInlet());
        updateWrapper.set(BasicMeter::getOutlet, meterData.getOutlet());
        updateWrapper.set(BasicMeter::getReadingTime, meterData.getReadingTime());
        updateWrapper.eq(BasicMeter::getMeterId, meterData.getMeterId());
        basicMeterMapper.update(null, updateWrapper);

        double useHeat = meterData.getHeat() - meterData.getLastHeat();
        double useFlow = meterData.getFlow() - meterData.getLastFlow();
        meterData.setUseHeat(useHeat);
        meterData.setUseFlow(useFlow);
        meterData.setUpdateTime(DateUtils.getNowDate());
        //保存抄表记录
        DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.SLAVE.name());
        int rows = baseMapper.updateById(meterData);
        DynamicDataSourceContextHolder.clearDataSourceType();

        alarmDataService.insertAlarmData(meterData);
        return rows;
    }

    /**
     * 批量抄表
     *
     * @param meterIds 需要抄表的表id
     * @return 结果
     */
    @Override
    public String readingMeterData(String meterIds, String operName){
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (Long meterId : Convert.toLongArray(meterIds)) {
            BasicMeter basicMeter = basicMeterMapper.selectBasicMeterById(meterId);
            if (redisService.hHasKey("sys-netty", basicMeter.getDeviceCode())) {
                String controlOrder = "";
                if(basicMeter.getDeviceFactory().equals("01")) {
                    controlOrder = iecmParam.paramRead(basicMeter.getDeviceCode(), basicMeter.getMeterNo(), basicMeter.getMeterFactory());
                }

                //保存抄表记录
                MeterData meterData = new MeterData();
                meterData.setMeterId(basicMeter.getMeterId());
                meterData.setLastHeat(basicMeter.getHeat());
                meterData.setLastFlow(basicMeter.getFlow());
                meterData.setControlOrder(controlOrder.replace(" ", ""));
                meterData.setCreateBy(operName);
                meterData.setCreateTime(DateUtils.getNowDate());
                meterData.setRemark(basicMeter.getMeterNo() + "热表数据采集");
                DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.SLAVE.name());
                baseMapper.insert(meterData);
                DynamicDataSourceContextHolder.clearDataSourceType();

                //将要采集的表信息发送到rabbitmq
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("meterNo", basicMeter.getMeterNo());
                jsonObject.put("deviceCode", basicMeter.getDeviceCode());
                jsonObject.put("receiveStr", controlOrder);
                jsonObject.put("mark", basicMeter.getMeterNo() + "热表数据采集");

                rabbitService.sendWorkQueue("job_queue", jsonObject);

                successNum++;
                successMsg.append("<br/>" + successNum + "、表号 " + basicMeter.getMeterNo() + " 发送抄表命令成功");
            } else {
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、表号 " + basicMeter.getMeterNo() + " 不在线，发送抄表命令失败");
            }
        }
        if (failureNum > 0)
        {
            failureMsg.insert(0, "很抱歉，抄表失败！共 " + failureNum + " 只表设备发送抄表命令失败，错误如下：");
            return failureMsg.toString();
        }
        return successMsg.toString();
    }

    /**
     * 根据表id查询最后一条抄表记录
     * @param meterId
     * @return
     */
    @DataSource(DataSourceType.SLAVE)
    public MeterData selectMeterDataByMeterId(Long meterId) {
        return baseMapper.selectOne(Wrappers.lambdaQuery(MeterData.class)
                .eq(MeterData::getMeterId, meterId)
                .eq(MeterData::getReturnFlag, "0")
                .orderByDesc(MeterData::getCreateTime).last("limit 1"));
    }

    /**
     * 批量抄表
     *
     * @param deviceId 需要抄表的表id
     * @return 结果
     */
    @Override
    public void readingMeterDataByDevice(Long deviceId, String deviceCode, String operName){
        List<BasicMeter> meterList = basicMeterMapper.selectBasicMeterByDeviceId(deviceId);
        for (BasicMeter basicMeter : meterList) {
            String controlOrder = "";
            if(basicMeter.getDeviceFactory().equals("01")) {
                controlOrder = iecmParam.paramRead(basicMeter.getDeviceCode(), basicMeter.getMeterNo(), basicMeter.getMeterFactory());
            }

            //保存抄表记录
            MeterData meterData = new MeterData();
            meterData.setMeterId(basicMeter.getMeterId());
            meterData.setLastHeat(basicMeter.getHeat());
            meterData.setLastFlow(basicMeter.getFlow());
            meterData.setControlOrder(controlOrder.replace(" ", ""));
            meterData.setCreateBy(operName);
            meterData.setCreateTime(DateUtils.getNowDate());
            meterData.setRemark(basicMeter.getMeterNo() + "热表数据采集");
            DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.SLAVE.name());
            baseMapper.insert(meterData);
            DynamicDataSourceContextHolder.clearDataSourceType();

            //将要采集的表信息发送到rabbitmq
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("meterNo", basicMeter.getMeterNo());
            jsonObject.put("deviceCode", basicMeter.getDeviceCode());
            jsonObject.put("receiveStr", controlOrder);
            jsonObject.put("mark", basicMeter.getMeterNo() + "热表数据采集");

            redisService.lSet("device:" + deviceCode, jsonObject);
        }
        rabbitService.sendWorkQueue("device_queue", deviceCode);
    }
}
